package runze.shiro.web;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import runze.shiro.domain.User;
import runze.shiro.service.UserService;
import runze.shiro.validator.LoginValidator;
import runze.shiro.validator.SignupValidator;
import runze.shiro.vo.LoginCommand;
import runze.shiro.vo.SignupCommand;

/**
 * 登录
 * @author wrzhxy@qq.com
 * @date 2017年12月29日
 */
@RestController
@Scope("prototype")
public class LoginController {
	@PostMapping("/login")
	public String login(@ModelAttribute LoginCommand command, BindingResult errors) {
		LoginValidator loginValidator = new LoginValidator();
		loginValidator.validate(command, errors);

        if( errors.hasErrors() ) {
            return "login validate failed";
        }
        
		Subject currentUser = SecurityUtils.getSubject();
		Session session = currentUser.getSession();
		session.setAttribute("someKey", "aValue");
		String value = (String) session.getAttribute("someKey");
		
		if (!currentUser.isAuthenticated()) {
		    UsernamePasswordToken token = new UsernamePasswordToken(command.getUsername(), command.getPassword());
		    token.setRememberMe(command.isRememberMe());
		    try {
		        currentUser.login(token);
		        System.out.println("登录成功");
		        return "200";
		    } catch (UnknownAccountException uae) {
		        System.out.println("There is no user with username of " + token.getPrincipal());
		    } catch (IncorrectCredentialsException ice) {
		        System.out.println("Password for account " + token.getPrincipal() + " was incorrect!");
		    } catch (LockedAccountException lae) {
		        System.out.println("The account for username " + token.getPrincipal() + " is locked.  " +
		                "Please contact your administrator to unlock it.");
		    }
		    // ... catch more exceptions here (maybe custom ones specific to your application?
		    catch (AuthenticationException ae) {
		        //unexpected condition?  error?
		    	System.out.println("else");
		    }
		    return "403";
		}
		System.out.println("登录步骤完成");
		return "200";
	}
	
	private SignupValidator signupValidator = new SignupValidator();

    @Autowired
    private UserService userService;
    
	@PostMapping("/signup")
    public String signup(Model model, @ModelAttribute SignupCommand command, BindingResult errors) {
        signupValidator.validate(command, errors);
System.out.println("post signup");
        if( errors.hasErrors() ) {
//            return showSignupForm(model, command);
            return "signup validate failed";
        }
        
        User user = new User(command.getUsername(), command.getPassword(), command.getEmail());
        // Create the user
        userService.createUser( user );

        // Login the newly created user
        SecurityUtils.getSubject().login(new UsernamePasswordToken(command.getUsername(), command.getPassword()));

        return "signup user!";
    }
	
	@GetMapping("/welcome")
	public String welcome() {
		return "welcome";
	}
	@GetMapping("/403")
	public String r403() {
		return "403";
	}
	@RequestMapping("/logout")
    public String logout() {
        SecurityUtils.getSubject().logout();
        return "loginout";
    }
}
